---
title: Search as we type
---

Ein Beispiel aus der Praxis könnte die Verwendung von `FutureProvider` 
zur Implementierung einer Suchleiste sein.

## Beispiel für die Verwendung: "Suche während der Eingabe" Suchleiste

Die Implementierung einer "Suche während der Eingabe" kann anfangs, 
mit herkömmlichen Mitteln, entmutigend erscheinen. Es gibt viele 
bewegliche Teile, wie zum Beispiel:

- Behandlung von Fehlern.
- debouncing der Benutzereingabe, um zu vermeiden, dass bei jedem Tastendruck Netzanfragen gestellt werden.
- Stornierung bereits laufender Netzanfragen, wenn sich das Suchfeld ändert.

Aber die Kombination von `FutureProvider` und der Funktionen von 
[ref.watch] kann diese Aufgabe erheblich vereinfachen.

Ein gängiges Muster für die Durchführung asynchroner Anforderungen 
ist die Aufteilung in mehrere Provider:

- ein [StateNotifierProvider] oder `StateProvider` für die Parameter deiner Anfrage
  (oder benutze alternativ [family])
- ein `FutureProvider`, der die Anfrage abschickt. Dafür liest er die Parameter
  von anderen Providern/[family].

Der erste Schritt wäre, die Benutzereingaben irgendwo zu speichern. Für dieses Beispiel, 
werden wir `StateProvider` verwenden (da der Suchstatus nur ein einzelner `String` ist):

```dart
final searchInputProvider = StateProvider<String>((ref) => '');
```

Wir können dann diesen Provider mit einem [TextField] verbinden, indem wir folgendes tun:

```dart
Consumer(
  builder: (context, ref, child) {
    return TextField(
      onChanged: (value) => ref.read(searchInputProvider.notifier).state = value,
    );
  },
)
```

Dann können wir einen `FutureProvider` erstellen, der sich um die Anfrage kümmern wird:

```dart
final searchProvider = FutureProvider<


<!--
// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

final searchFieldProvider = StateProvider<String>((ref) => '');
final questionsProvider = FutureProvider<List>((ref) async {
  final client = http.Client();
  ref.onDispose(client.close);

  final search = ref.watch(searchFieldProvider);

  Uri uri;

  if (search.isEmpty) {
    uri = Uri.parse(
      'https://api.stackexchange.com/2.3/questions?order=desc&sort=activity&site=stackoverflow',
    );
  } else {
    final encodedQuery = Uri.encodeComponent(search);
    uri = Uri.parse(
      'https://api.stackexchange.com/2.3/search?order=desc&sort=activity&intitle=$encodedQuery&site=stackoverflow',
    );
  }

  final response = await client.get(uri);
  final questions = jsonDecode(response.body);

  return questions['items'].map((question) => question['title']).toList();
});

void main() => runApp(const ProviderScope(child: MyApp()));

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: MyHomePage());
  }
}

class MyHomePage extends ConsumerWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final questions = ref.watch(questionsProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Questions')),
      body: Column(
        children: [
          TextField(
            onChanged: (value) =>
                ref.read(searchFieldProvider.notifier).state = value,
          ),
          Expanded(
            child: questions.when(
              loading: () => const Center(child: CircularProgressIndicator()),
              error: (error, stack) => Center(child: Text('Error $error')),
              data: (questions) {
                return ListView.builder(
                  itemCount: questions.length,
                  itemBuilder: (context, index) {
                    final question = questions[index];

                    return ListTile(
                      title: Text(
                        question.toString(),
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}
```
